package com.zzyl.nursing.service.impl;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.time.LocalDateTime;

import com.google.common.collect.Maps;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import com.zzyl.nursing.util.IDCardUtils;
import com.zzyl.nursing.vo.SystemScore;
import com.zzyl.nursing.vo.HealthAssessmentVo;
import com.zzyl.nursing.vo.RiskDistributionVo;

import java.util.Arrays;
import java.util.List;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.zzyl.common.constant.Constants;
import com.zzyl.common.core.redis.RedisCache;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.ai.BaiDuInvoker;
import com.zzyl.nursing.dto.HealthAssessmentDto;
import com.zzyl.nursing.vo.HealthReportVo;
import io.lettuce.core.RedisClient;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.HealthAssessmentMapper;
import com.zzyl.nursing.domain.HealthAssessment;
import com.zzyl.nursing.service.IHealthAssessmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 健康评估Service业务层处理
 *
 * @author JBY
 * @date 2025-08-16
 */
@Service
public class HealthAssessmentServiceImpl extends ServiceImpl<HealthAssessmentMapper, HealthAssessment> implements IHealthAssessmentService {
    @Autowired
    private HealthAssessmentMapper healthAssessmentMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private BaiDuInvoker baiDuInvoker;

    /**
     * 查询健康评估
     *
     * @param id 健康评估主键
     * @return 健康评估
     */
    @Override
    public HealthAssessment selectHealthAssessmentById(Long id) {
        return healthAssessmentMapper.selectById(id);
    }

    /**
     * 查询健康评估列表
     *
     * @param healthAssessment 健康评估
     * @return 健康评估
     */
    @Override
    public List<HealthAssessment> selectHealthAssessmentList(HealthAssessment healthAssessment) {
        return healthAssessmentMapper.selectHealthAssessmentList(healthAssessment);
    }

    /**
     * 新增健康评估
     *
     * @param healthAssessmentDto 健康评估
     * @return 结果
     */
    @Override
    public Long insertHealthAssessment(HealthAssessmentDto healthAssessmentDto) {
        // 1. 组装AI提示词
        String prompt = getPrompt(healthAssessmentDto);
        // 2. 调用AI接口, 获取结果
        String result = null;
        try {
            result = baiDuInvoker.QianfanInvoker(prompt);
            if (StrUtil.isBlank(result)) {
                throw new BaseException("大模型解析内容为空");
            }
        } catch (Exception e) {
            throw new BaseException("大模型解析失败");
        }
        // 3. 保存, 返回ID
        return saveHealthAssessment(healthAssessmentDto, result);
    }

    private Long saveHealthAssessment(HealthAssessmentDto healthAssessmentDto, String result) {
        // 1. 解析大模型结果 将大模型返回的JSON转为对象
        HealthReportVo healthReportVo = JSONUtil.toBean(result, HealthReportVo.class);
        // 2. 从大模型结果中获取健康评估信息
        HealthAssessmentVo healthAssessmentVo = healthReportVo.getHealthAssessment();
        // 3. 获取身份证号
        String idCard = healthAssessmentDto.getIdCard();

        // 4. 封装结果存入数据库
        HealthAssessment healthAssessment = new HealthAssessment();
        healthAssessment.setElderName(healthAssessmentDto.getElderName());
        healthAssessment.setIdCard(idCard);
        healthAssessment.setBirthDate(IDCardUtils.getBirthDateByIdCard(idCard));
        healthAssessment.setAge(IDCardUtils.getAgeByIdCard(idCard));
        healthAssessment.setGender(IDCardUtils.getGenderFromIdCard(idCard));
        healthAssessment.setHealthScore(String.valueOf(healthAssessmentVo.getHealthIndex()));
        healthAssessment.setRiskLevel(healthAssessmentVo.getRiskLevel());
        healthAssessment.setSuggestionForAdmission(healthAssessmentVo.getHealthIndex() > 60 ? 0 : 1);
        healthAssessment.setNursingLevelName(getNursingLevel(healthAssessmentVo.getHealthIndex()));
        healthAssessment.setAdmissionStatus(1);
        healthAssessment.setTotalCheckDate(healthReportVo.getTotalCheckDate());
        healthAssessment.setPhysicalExamInstitution(healthAssessmentDto.getPhysicalExamInstitution());
        healthAssessment.setPhysicalReportUrl(healthAssessmentDto.getPhysicalReportUrl());
        healthAssessment.setAssessmentTime(LocalDateTime.now());
        healthAssessment.setReportSummary(healthReportVo.getSummarize());
        healthAssessment.setDiseaseRisk(JSONUtil.toJsonStr(healthReportVo.getRiskDistribution()));
        healthAssessment.setAbnormalAnalysis(JSONUtil.toJsonStr(healthReportVo.getAbnormalData()));
        healthAssessment.setSystemScore(JSONUtil.toJsonStr(healthReportVo.getSystemScore()));
        try {
            healthAssessmentMapper.insert(healthAssessment);
        } catch (Exception e) {
            throw new BaseException("新增健康评估信息失败");
        }
        return healthAssessment.getId();
    }

    /**
     * 根据健康分数获取护理等级
     *
     * @param: healthIndex
     * @return: String
     */
    private String getNursingLevel(double healthIndex) {
        if (healthIndex >= 90) {
            return "四级护理等级";
        } else if (healthIndex >= 80) {
            return "三级护理等级";
        } else if (healthIndex >= 70) {
            return "二级护理等级";
        } else if (healthIndex >= 60) {
            return "一级护理等级";
        } else {
            return "特级护理等级";
        }
    }

    private String getPrompt(HealthAssessmentDto healthAssessmentDto) {
        //从redis中获取体检报告, 校验非空
        String report = (String) redisTemplate.opsForHash().get(Constants.CACHE_HEALTH_ASSESSMENT, healthAssessmentDto.getIdCard());
        if (StrUtil.isBlank(report)) {
            throw new BaseException("未找到体检报告");
        }
        //在从缓存中获取到体检报告后, 就可以删除Redis中的体检报告缓存了
        try {
            redisTemplate.opsForHash().delete(Constants.CACHE_HEALTH_ASSESSMENT, healthAssessmentDto.getIdCard());
        } catch (Exception e) {
            log.error("删除Redis中的体检报告缓存失败");
        }
        //组装AI提示词 返回

        StringBuilder sbr = new StringBuilder();
        List<String> strings = IOUtils.readLines(this.getClass().getClassLoader().getResourceAsStream("prompts/prompt1.txt"), StandardCharsets.UTF_8);
        strings.forEach(line -> sbr.append(line).append("\n"));
        sbr.append(report).append("\n");
        strings = IOUtils.readLines(this.getClass().getClassLoader().getResourceAsStream("prompts/prompt2.txt"), StandardCharsets.UTF_8);
        strings.forEach(line -> sbr.append(line).append("\n"));
        return sbr.toString();
    }

    /**
     * 修改健康评估
     *
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public int updateHealthAssessment(HealthAssessment healthAssessment) {
        return healthAssessmentMapper.updateById(healthAssessment);
    }

    /**
     * 批量删除健康评估
     *
     * @param ids 需要删除的健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentByIds(Long[] ids) {
        return healthAssessmentMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除健康评估信息
     *
     * @param id 健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentById(Long id) {
        return healthAssessmentMapper.deleteById(id);
    }
}
